import os
from typing import List
import pandas as pd
from .df_table import DFTable
import feffery_antd_components as fac
from dash import callback, Output, Input, State, dcc, html, MATCH, no_update,ctx

def format_file_size(size_bytes):
    """将字节大小转换为合适的单位（KB或MB）。"""
    if size_bytes < 1024:
        return f"{size_bytes} B"
    elif size_bytes < 1024 ** 2:
        return f"{size_bytes / 1024:.2f} KB"
    else:
        return f"{size_bytes / (1024 ** 2):.2f} MB"
    
class DirFilesTable:
    instance_store = {}  # 用于存储实例

    def __init__(
        self,
        name: str,
        dir: str,
        filter_names: List[str] = None,
        filter_suffixes: List[str] = None,
        enable_download=False,
        enable_delete=False,
    ):
        self.name = name
        self.dir = dir
        self.filter_names = filter_names
        self.filter_suffixes = filter_suffixes
        self.enable_download = enable_download
        self.enable_delete = enable_delete
        # 涉及组件id
        self.table_id = {"type": "dirfiles-table", "index": self.name}
        self.download_id = {"type": "download-dirfiles", "index": self.name}
        self.notification_id = {"type": "notification-dirfiles", "index": self.name}
        # 将实例存入类变量
        DirFilesTable.instance_store[name] = self

    def get_fileinfo_df(self):
        dir = self.dir
        # 确保保存目录存在
        if os.path.exists(dir):
            # 获取目录中的文件信息
            files = []
            for filename in os.listdir(dir):
                filepath = os.path.join(dir, filename)
                if os.path.isfile(filepath):
                    file_info = {
                        "文件名": filename,
                        "大小": format_file_size(os.path.getsize(filepath)),  # 格式化文件大小
                        "最后修改时间": pd.Timestamp(
                            os.path.getmtime(filepath), unit="s",tz='Asia/Shanghai'
                        ).strftime("%Y-%m-%d %H:%M:%S"),
                    }
                    files.append(file_info)
            # 将文件信息转换为 DataFrame并返回
            if len(files) > 0:
                return pd.DataFrame(files)
        return pd.DataFrame(columns=["文件名", "大小", "最后修改时间"])

    def get_cols(self):
        cols = [
            {
                "title": c,
                "dataIndex": c,
            }
            for c in self.get_fileinfo_df()
        ]
        if any([self.enable_delete, self.enable_download]):
            cols.extend(
                [
                    {
                        "title": "操作",
                        "dataIndex": "操作",
                        "renderOptions": {
                            "renderType": "button",
                            "renderButtonPopConfirmProps": {
                                "title": "确认执行？",
                                "okText": "确认",
                                "cancelText": "取消",
                            },
                        },
                    }
                ]
            ),
        return cols

    def get_data(
        self,
    ):
        data = self.get_fileinfo_df().to_dict("records")
        if self.enable_download:
            element = {
                "content": "下载",
                "type": "primary",
                "custom": "download",
            }
            for d in data:
                elements: List | None = d.get("操作")
                if not elements:
                    elements = [element]
                    d["操作"] = elements
                else:
                    elements.append(element)
        if self.enable_delete:
            element = {
                "content": "删除",
                "type": "primary",
                "custom": "delete",
                "danger": True,
            }
            for d in data:
                elements: List | None = d.get("操作")
                if not elements:
                    elements = [element]
                    d["操作"] = elements
                else:
                    elements.append(element)
        return data

    def get_table(self):
        table = fac.AntdTable(
            id=self.table_id,
            columns=self.get_cols(),
            data=self.get_data(),
        )
        self.table = table
        return table

    def refresh_table(self):
        self.table.data = self.get_data()

    @property
    def layout(self):
        components = []
        table = self.get_table()
        components.append(table)
        components.append(
            dcc.Download(id=self.download_id)
        )
        notification = html.Div(id=self.notification_id)
        components.append(notification)
        return html.Div(components)


@callback(
    Output({"type": "dirfiles-table", "index": MATCH}, "data", allow_duplicate=True),
    Output(
        {"type": "notification-dirfiles", "index": MATCH},
        "children",
        allow_duplicate=True,
    ),
    Output(
        {"type": "download-dirfiles", "index": MATCH},
        "data",
        allow_duplicate=True,
    ),
    Input({"type": "dirfiles-table", "index": MATCH}, "nClicksButton"),
    [
        State({"type": "dirfiles-table", "index": MATCH}, "clickedCustom"),
        State(
            {"type": "dirfiles-table", "index": MATCH},
            "recentlyButtonClickedRow",
        ),
    ],
    prevent_initial_call=True,
)
def handle_download_delete(
    nClicksButton,
    clickedCustom,
    recentlyButtonClickedRow,
):
    filetable_instance: DirFilesTable = DirFilesTable.instance_store[ctx.triggered_id["index"]]
    filename = recentlyButtonClickedRow["文件名"]
    filepath = os.path.join(filetable_instance.dir, filename)
    if clickedCustom == "download":
        return no_update, no_update, dcc.send_file(filepath)
    elif clickedCustom == "delete":
        os.remove(filepath)
        return (
            filetable_instance.get_data(),
            fac.AntdNotification(
                message="删除成功",
                description=f"成功删除文件{filename}",
                type="success",
            ),
            no_update,
        )
